// -*-mode:c++; coding:utf-8-*-

#ifndef _XBASE_IO_SERVICE_POOL_HPP_
#define _XBASE_IO_SERVICE_POOL_HPP_

#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <boost/asio/io_service.hpp>

#include "client_options.hpp"

namespace xbase
{

	class io_service_pool
		: private boost::noncopyable
	{
	public:
		typedef boost::shared_ptr<io_service_pool> ptr_type;
		
	public:
		struct _1st_level {
			static const std::size_t value = 1;
		};
		struct _2nd_level {
			static const std::size_t value = 2;
		};
		struct _3rd_level {
			static const std::size_t value = 3;
		};

		typedef _1st_level socket_level;
		typedef _2nd_level xbase_level;
		typedef _3rd_level user_level;

	public:
		virtual ~io_service_pool() {}

		virtual void run() = 0;
		virtual void stop() = 0;
		virtual void join() = 0;

		template<typename Level>
		boost::asio::io_service &get_io_service();

		const client_options &options() const {
			return *m_options;
		}

		// 在 client_environment 中自动设置
		void set_options(const client_options &options) {
			m_options = &options;
		}

	private:
		virtual
		boost::asio::io_service &get_1st_level_io_service() = 0;

		virtual
		boost::asio::io_service &get_2nd_level_io_service() = 0;

		virtual
		boost::asio::io_service &get_3rd_level_io_service() = 0;

	private:
		const client_options *m_options;
	};

	typedef io_service_pool::ptr_type io_service_pool_ptr;

	template<>
	inline
	boost::asio::io_service &io_service_pool::get_io_service<io_service_pool::_1st_level>()
	{
		return this->get_1st_level_io_service();
	}

	template<>
	inline
	boost::asio::io_service &io_service_pool::get_io_service<io_service_pool::_2nd_level>()
	{
		return this->get_2nd_level_io_service();
	}

	template<>
	inline
	boost::asio::io_service &io_service_pool::get_io_service<io_service_pool::_3rd_level>()
	{
		return this->get_3rd_level_io_service();
	}

} // namespace xbase

#endif	// _XBASE_IO_SERVICE_POOL_HPP_
